#pragma warning(disable : 4355)
#include "Avalon/Network/TcpSocketWriter.hpp"
#include <boost/bind.hpp>
#include "Avalon/IO/NotConnectedException.hpp"
#include "Avalon/Network/SocketException.hpp"
#include "Avalon/Network/SocketType.hpp"
#include "Avalon/Network/TcpSocketConnection.hpp"

using namespace Avalon;
using namespace Avalon::IO;
using namespace Avalon::Network;
using namespace Avalon::Network::Detail;
using namespace Avalon::Threading;
using namespace boost;
using namespace boost::asio;
using namespace boost::asio::ip;
using namespace boost::posix_time;
using namespace std;

TcpSocketWriter::~TcpSocketWriter() {}

void TcpSocketWriter::Write(const void* data, int size,
    Out<Async<void> > result) {
  m_result = result.Get();
  async_write(m_socket->m_socket, buffer(data, size), m_writeSlot);
}

void TcpSocketWriter::Write(const Buffer& data, Out<Async<void> > result) {
  m_data = data;
  m_result = result.Get();
  async_write(m_socket->m_socket, buffer(m_data.GetData(), m_data.GetSize()),
    m_writeSlot);
}

TcpSocketWriter::TcpSocketWriter(const shared_ptr<SocketType>& socket)
    : m_socket(socket),
      m_writeSlot(bind(&TcpSocketWriter::OnWrite, this, _1, _2)) {}

void TcpSocketWriter::OnWrite(const system::error_code& error, size_t size) {
  if(error) {
    m_result->SetException(SocketException(error.value(), error.message()));
  } else {
    m_result->SetResult();
  }
}
